/*
 * @(#)WorkflowMessageFormatter.java 
 * Copyright (c) 2006 DCIVision Ltd All rights reserved.
 * 
 *  This software is the confidential and proprietary information of DCIVision Ltd 
 *  ("Confidential Information"). You * shall not disclose such Confidential
 *   Information and shall use it only in accordance with the terms of the 
 *   license agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.alert.core;

import java.sql.Connection;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.alert.bean.UpdateAlert;
import com.dcivision.alert.bean.UpdateAlertSystemLog;
import com.dcivision.dms.bean.DmsDocument;
import com.dcivision.form.bean.FormRecord;
import com.dcivision.form.bean.FormSubmission;
import com.dcivision.form.dao.FormRecordDAObject;
import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.SessionContainer;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.UserInfoFactory;
import com.dcivision.framework.Utility;
import com.dcivision.user.bean.UserDelegation;
import com.dcivision.user.dao.UserDelegationDAObject;
import com.dcivision.workflow.bean.MtmWorkflowProgressSystemObject;
import com.dcivision.workflow.bean.MtmWorkflowTrackInterruptReq;
import com.dcivision.workflow.bean.WorkflowProgress;
import com.dcivision.workflow.bean.WorkflowRecord;
import com.dcivision.workflow.bean.WorkflowStep;
import com.dcivision.workflow.dao.MtmWorkflowProgressSystemObjectDAObject;
import com.dcivision.workflow.dao.WorkflowProgressDAObject;
import com.dcivision.workflow.dao.WorkflowRecordDAObject;
import com.dcivision.workflow.dao.WorkflowStepRouteDAObject;

/**
 * <p>
 * Class Name: WorkflowMessageFormatter
 * </p>
 * 
 * @author Greatwall shao
 * @company DCIVision Limited
 * @creation date 2006-11-06
 */
public class WorkflowMessageFormatter extends AbstractMessageFormatter {
  protected String  workflowRecordID;

  protected Integer workflowTrackID;
  
  private static final Log log = LogFactory.getLog(WorkflowMessageFormatter.class);
  public WorkflowMessageFormatter(UpdateAlertSystemLog bean, SessionContainer sessionContainer,
      Connection dbConn) throws ApplicationException {
    super(bean, sessionContainer, dbConn);
  }

  public String getSubject() {
    String str = "";
    str = "<a class=\"strongllink\" href=\"#\" "
        + " title = \" "
        + getSubjectAsTitle()
        + " \" "
        + "onClick=\"OpenCenteredPopup('workflow/MaintWorkflowTask.do?SHOW_HEADER_FOOTER=N&navMode=E&trackID="
        + workflowTrackID.toString()
        + "&ID="
        + updateAlertSystemLog.getObjectID().toString()
        +"&isFromMessageManager=true"
        + "&systemLogID="
        + updateAlertSystemLog.getID();
    
    if(!isList()){
      str +=  "&isFromHomeMessageInbox=true";
    }
    
    str +=  "&workflowRecordID="
        + this.workflowRecordID
        + "', 'DCIVisionViewWorkflowProgress', '850', '600', 'status=no,menubar=no,scrollbars=yes,resizable=yes,toolbar=no');\">";
    str += getProperLengSubject();
    str += "</a>";
    return str;
  }

  private void makeWorkflow() throws ApplicationException {
    String actionType = getActionType();
    String taskName = "";
    String stepName = "";

    WorkflowProgressDAObject progressDAO = new WorkflowProgressDAObject(sessionContainer, dbConn);
    WorkflowProgress workflowProgress = (WorkflowProgress) progressDAO
        .getObjectByID(updateAlertSystemLog.getObjectID());
    WorkflowStep workflowStep = workflowProgress.getWorkflowStepSource();
    this.workflowTrackID = workflowProgress.getTrackID();
    Integer submitUserID = progressDAO.getUserIDForWorkflowTrackSubmitter(workflowTrackID);
    this.workflowRecordID = workflowProgress.getWorkflowRecordID().toString();
    
    String submitter = UserInfoFactory.getUserFullName(submitUserID);
    stepName = workflowStep.getStepName();

    String trackStr = TextUtility.formatNumberWithZeroPrefix(SystemParameterFactory
        .getSystemParameterInteger(SystemParameterConstant.WORKLFLOW_TRACK_ID_FORMAT_LENGTH)
        .intValue(), workflowTrackID);

    String formBindTitle = getWorkflowBindTitle();
    if(!Utility.isEmpty(formBindTitle)){
      trackStr = trackStr +"-"+formBindTitle;
    }
    taskName = this.getMessageResource("home.message.workflow_notification.task", stepName,
        trackStr, submitter);

    if (UpdateAlert.NOTIFY_TASK_ARRIVED_ACTION.equals(actionType)) {
      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_arrive", trackStr,stepName);

    }
    else if (UpdateAlert.DELEGATION_ACTION.equals(actionType)) {
      UserDelegationDAObject delegationDAO = new UserDelegationDAObject(sessionContainer, dbConn);
      String delegationUserName = "";
      String delegationDateRange = "date range";
      try {
        UserDelegation delegation = (UserDelegation) delegationDAO.getByIDStatus(updateAlertSystemLog
            .getObjectID(),null);
        Integer sourceUserID = new Integer("0");
        sourceUserID = delegation.getSourceUserID();
        delegationUserName = UserInfoFactory.getUserFullName(sourceUserID);
        String delegationStartDate = TextUtility.formatTimestampToDate(delegation.getStartDate());
        String delegationEndDate = TextUtility.formatTimestampToDate(delegation.getEndDate());
        if(!Utility.isEmpty(delegationEndDate)){
          delegationDateRange = delegationStartDate +" to " + delegationEndDate;
        }
      }
      catch (Exception e) {
        log.error(e, e);
      }

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_delegate", delegationUserName, delegationDateRange);
    }
    else if (UpdateAlert.NOTIFY_DELEGATION_USER.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_delegate_to_you", userName,trackStr,stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_COMPLETED_ACTION.equals(actionType)
        || UpdateAlert.NOTIFY_TASK_COMPLETED_BY_USER.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_complete", trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_APPROVED.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_approved", trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_REJECT.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_rejected", trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_YES.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_selected_yes", trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_NO.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_selected_no", trackStr, stepName);
    }
    else if (actionType.indexOf(UpdateAlert.NOTIFY_TASK_DECISION) == 0) {
      String routeName=getRouteName(actionType, workflowStep);
      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_selected_decision", routeName,trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_PRIORITY_CHANGED.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_priority_change", trackStr,stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(actionType)
        || UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_overdue", trackStr,stepName);
    }
    else if (UpdateAlert.ALERT_TYPE.equals(actionType)
        || UpdateAlert.REMIND_ACTION.equals(actionType)
        || UpdateAlert.NOTIFY_BEFORE_DUE_DATE.equals(actionType)) {

      String dateStr = "N/A";
      if (!Utility.isEmpty(workflowProgress.getDueDate())) {
        dateStr = TextUtility.formatTimestamp(workflowProgress.getDueDate());
      }
      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_reminder", trackStr,stepName, dateStr);
    }
    else if (UpdateAlert.NOTIFY_STOP_TRACK.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_stop", trackStr,stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_COMPLETED_BY_USER.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_completed_by_user", taskName, userName);
    }
    else if (UpdateAlert.NOTIFY_TASK_CHECK_OUT_BY_USER.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_check_out_by_user", trackStr, stepName);
    }
    else if (UpdateAlert.NOTIFY_TASK_IN_PROGRESSING.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_progressing", taskName);
    }
    else if (UpdateAlert.NOTIFY_TASK_PENDING_FOR.equals(actionType)) {

      this.messageSubject = this.getMessageResource(
          "home.message.workflow_notification.task_pending", trackStr,stepName);
    }
  }
/**
 * get the route name
 * @param actionType
 * @param workflowStep
 * @return routeName
 * @throws ApplicationException
 */
  private String getRouteName(String actionType, WorkflowStep workflowStep) {
    String routeName="";
    WorkflowStepRouteDAObject routeDAO = new WorkflowStepRouteDAObject(sessionContainer, dbConn);
    try {
      String sub = actionType.substring(1);
      int id = Integer.parseInt(sub);
      routeName = routeDAO.getRouteNameByStepIDAndSeq(workflowStep.getID(), id);
    } catch (Exception exp) {
     
    }
    return routeName;
  }

  /**
   * 
   * @return String workflowBindTitle
   * @throws ApplicationException
   */
  private String getWorkflowBindTitle() throws ApplicationException {
    FormRecordDAObject formRecordDAO = new FormRecordDAObject(sessionContainer, dbConn);
    MtmWorkflowProgressSystemObjectDAObject mtmWfProgSysObjDAO = new MtmWorkflowProgressSystemObjectDAObject(sessionContainer, dbConn);
    List relatedObjList = mtmWfProgSysObjDAO.getListByTrackID(workflowTrackID);
    String workflowBindTitle = new String();
    
    for (int i = 0; i < relatedObjList.size(); i++) {
      MtmWorkflowProgressSystemObject relatedObj = (MtmWorkflowProgressSystemObject) relatedObjList.get(i);
      if (relatedObj != null && relatedObj.getParameterObject() != null) {
        java.util.Map dataMap = (java.util.Map) relatedObj.getParameterObject();
        Object workflowObj = dataMap.get("WORKFLOW_OBJECT");
        if (workflowObj instanceof DmsDocument) {
          workflowBindTitle = getWorkflowBindDocumentName(workflowObj);
        } else if (workflowObj instanceof FormSubmission) {
          workflowBindTitle = getWorkflowBindFormTitle(formRecordDAO, workflowObj);
        } else if (workflowObj instanceof MtmWorkflowTrackInterruptReq) {
          workflowBindTitle = getWorkflowInterrupWorkflowCode(dataMap);
        }
      }
    }
    return workflowBindTitle;
  }

  /**
   * 
   * @param formRecordDAO
   * @param workflowObj
   * @throws ApplicationException
   */
  private String getWorkflowBindFormTitle(FormRecordDAObject formRecordDAO, Object workflowObj)
      throws ApplicationException {
    FormSubmission formSubmission = (FormSubmission) workflowObj;
    FormRecord formRecord = (FormRecord) formRecordDAO.getObjectByID(formSubmission.getFormRecordID());
    return formRecord.getTitle();
  }

  /**
   * 
   * @param workflowObj
   */
  private String  getWorkflowBindDocumentName(Object workflowObj) {
    DmsDocument dmsDocment = (DmsDocument) workflowObj;
    return dmsDocment.getDocumentName();
  }

  /**
   * 
   * @param dataMap
   * @throws ApplicationException
   */
  private String getWorkflowInterrupWorkflowCode(java.util.Map dataMap) throws ApplicationException {
    WorkflowRecordDAObject workflowRecordDAO = new WorkflowRecordDAObject(sessionContainer, dbConn);
    WorkflowProgress wfProgress = (WorkflowProgress) dataMap.get("WORKFLOW_PROGRESS");
    WorkflowRecord wfRecord = (WorkflowRecord) workflowRecordDAO.getObjectByID(wfProgress.getWorkflowRecordID());
    return wfRecord.getWorkflowCode();
  }


  public String getSender() {
    String str = "";
    final Integer systemID = new Integer(0);
    Integer userID = updateAlertSystemLog.getActionUserID();
    if (UpdateAlert.NOTIFY_TASK_ALL_OVERDUE_ACTION.equals(updateAlertSystemLog.getActionType())
        || UpdateAlert.NOTIFY_TASK_OWNER_OVERDUE_ACTION.equals(updateAlertSystemLog.getActionType())
        || UpdateAlert.NOTIFY_TASK_PENDING_FOR.equals(updateAlertSystemLog.getActionType())
        || UpdateAlert.ALERT_TYPE.equals(updateAlertSystemLog.getActionType())
        || UpdateAlert.REMIND_ACTION.equals(updateAlertSystemLog.getActionType())
        || UpdateAlert.NOTIFY_BEFORE_DUE_DATE.equals(updateAlertSystemLog.getActionType()) || systemID.equals(userID)) {
      str = "System";
    } else {
      str = userName;
    }
    return str;
  }

  protected void makeMessageType() {

  }

  protected void setSystemMakeSubject() throws ApplicationException {
    makeWorkflow();
  }

  public String getUrlLink() {

    String str = "";
    str = "workflow/MaintWorkflowTask.do?SHOW_HEADER_FOOTER=N&navMode=E&trackID="
        + workflowTrackID.toString()
        + "&ID="
        + updateAlertSystemLog.getObjectID().toString()
        + "&workflowRecordID="
        + this.workflowRecordID;
    return str;
  
  }

}
